package aplicacion.vista;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import aplicacion.control.*;
import aplicacion.modelo.Modelo;
import aplicacion.modelo.Poligono;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import javax.swing.JFileChooser;

/**
 *
 * @author Ileana Natalia Díaz Palacios
 * Programación III
 * Universidad Nacional
 * 
 */
public class Interfaz extends JFrame implements Observer {

    public Interfaz(String titulo, int ancho, int altura,
            ControlAplicacion nuevoGestor) {
        super(titulo);
        setSize(ancho, altura);
        setMinimumSize(new Dimension(1240, 720));
        setResizable(true);
        setLocationByPlatform(true);

        gestorPrincipal = nuevoGestor;
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent we) {
                cerrarAplicacion();
            }
        });

        ajustarComponentes(getContentPane());
        gestorPrincipal.registrarObservador(this);
    }

    protected final void ajustarComponentes(Container c) {
        c.setLayout(new BorderLayout());

        // Sistema de menú de la aplicación.
        configurarMenus(c);

        // Configura la barra de herramientas.
        barraHerramientas = new JPanel();
        construirBarraHerramientas(barraHerramientas);
        c.add(BorderLayout.LINE_END, barraHerramientas);

        // Construye el área de dibujo.
        areaDibujo = new PanelDibujo();
        c.add(BorderLayout.CENTER, areaDibujo);

        // Barra de estado
        barraEstado = new JPanel();
        configurarBarraEstado(barraEstado);
        c.add(BorderLayout.PAGE_END, barraEstado);
    }

    final void construirBarraHerramientas(Container c) {
        JPanel barraHerramientas = new JPanel();

        barraHerramientas.setLayout(new GridLayout(7, 1, 1, 1));
        barraHerramientas.setBackground(Color.LIGHT_GRAY);


        // ** Por completar:
        // Agregar los botones de herramientas.

        ImageIcon cuadrado = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/cuadrado.png"));
        JButton cuadradito = new JButton(cuadrado);
        cuadradito.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.print(ae.getActionCommand());

                dibujarCuadrado();
            }
        });
        barraHerramientas.add(cuadradito);


        ImageIcon rectangulo = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/rectangulo.png"));
        JButton rectangulito = new JButton(rectangulo);
        rectangulito.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {

                dibujarRectangulo();
            }
        });
        barraHerramientas.add(rectangulito);

        ImageIcon rombo = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/rombo.png"));
        JButton rombito = new JButton(rombo);
        rombito.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                dibujarRombo();
            }
        });
        barraHerramientas.add(rombito);

        ImageIcon triangulo = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/triangulo.png"));
        JButton triangulito = new JButton(triangulo);
        triangulito.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                dibujarTriangulo();
            }
        });
        barraHerramientas.add(triangulito);

        ImageIcon rellenar = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/rellenar.png"));
        JButton relle = new JButton(rellenar);
        relle.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
            }
        });
        barraHerramientas.add(relle);

        ImageIcon borrar = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/borrador.png"));
        JButton borrarUltimo = new JButton(borrar);
        borrarUltimo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                borrar(false);
            }
        });
        barraHerramientas.add(borrarUltimo);

        ImageIcon borrarTo = new ImageIcon(getClass().getResource("/aplicacion/vista/imagenes/borrarTodo.png"));
        JButton borrarTodo = new JButton(borrarTo);
        borrarTodo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                borrar(true);
            }
        });
        barraHerramientas.add(borrarTodo);


        c.add(barraHerramientas);

    }

    private void configurarBarraEstado(JPanel barraEstado) {
        barraEstado.setLayout(new FlowLayout(FlowLayout.LEFT));
        barraEstado.add(msgInfo = new JLabel());
    }

    protected final void configurarMenus(Container c) {

        JMenuBar menuPrincipal = new JMenuBar();

        //////////////////// MENU ARCHIVO /////////////////////////

        JMenu menuArchivo = new JMenu("Archivo");
        menuArchivo.setMnemonic(KeyEvent.VK_A);
        menuArchivo.getAccessibleContext().setAccessibleDescription("Menu Principal");
        menuPrincipal.add(menuArchivo);

        //crea las acciones del menú "Archivo"

        JMenuItem nuevo = new JMenuItem("Nuevo", KeyEvent.VK_N);
        nuevo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
        nuevo.getAccessibleContext().setAccessibleDescription("Nueva pizarra de trabajo");
        nuevo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se debe realizar la opcion de limpiar toda la pizarra como si fuera un nuevo documento
            }
        });
        menuArchivo.add(nuevo);
        menuArchivo.addSeparator();

        abrir = new JMenuItem("Abrir", KeyEvent.VK_O);
        abrir.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
        abrir.getAccessibleContext().setAccessibleDescription("Abre algún documento guardado anteriormente");
        abrir.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se debe abrir una pantalla para seleccionar y abrir una imagen de cualquier lugar de la compu
                Object source = ae.getSource();
                if (source == abrir) {
                    abrirArchivo();
                } else {
                    JOptionPane.showMessageDialog(null, "No se puede abrir el menú. Inténtelo nuevamente.");
                }

            }
        });
        menuArchivo.add(abrir);
        menuArchivo.addSeparator();

        JMenuItem guardar = new JMenuItem("Guardar", KeyEvent.VK_G);
        guardar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.CTRL_MASK));
        guardar.getAccessibleContext().setAccessibleDescription("Guarda el documento en progreso");
        guardar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se debe guardar el documento, si no se ha hecho, se debe abrir el "guardar como" y seleccionar el formato
            }
        });
        menuArchivo.add(guardar);

        JMenuItem guardarComo = new JMenuItem("Guardar Como...");
        guardarComo.getAccessibleContext().setAccessibleDescription("Nueva pizarra de trabajo");
        guardarComo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se debe abrir una pantalla para seleccionar y abrir una imagen de cualquier lugar de la compu
            }
        });
        menuArchivo.add(guardarComo);
        menuArchivo.addSeparator();

        JMenuItem salir = new JMenuItem("Salir", KeyEvent.VK_ESCAPE);
        salir.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, ActionEvent.CTRL_MASK));
        salir.getAccessibleContext().setAccessibleDescription("Cierra la aplicación");
        salir.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //preguntar antes de cerrar si el documento está guardado, sino, guardarlo; se va a "guardar como"
                //si está guardado, preguntar si realmente se desea salir de la aplicacion
                cerrarAplicacion();
            }
        });
        menuArchivo.add(salir);

        ///////////// MENU EDITAR ////////////////

        JMenu menuEdicion = new JMenu("Edición");
        menuEdicion.setMnemonic(KeyEvent.VK_E);
        menuEdicion.getAccessibleContext().setAccessibleDescription("Edición de Imágenes");
        menuPrincipal.add(menuEdicion);

        // creacion de las acciones del menú "Editar"

        JMenuItem deshacer = new JMenuItem("Deshacer", KeyEvent.VK_Z);
        deshacer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));
        deshacer.getAccessibleContext().setAccessibleDescription("Regresa a la accion anterior");
        deshacer.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //regresa a lo ultimo que se realizó, eliminando lo actual
            }
        });
        menuEdicion.add(deshacer);
        menuEdicion.addSeparator();

        JMenuItem cortar = new JMenuItem("Cortar", KeyEvent.VK_X);
        cortar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
        cortar.getAccessibleContext().setAccessibleDescription("Corta el documento seleccionado");
        cortar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se debe cortar el documento
            }
        });
        menuEdicion.add(cortar);

        JMenuItem copiar = new JMenuItem("Copiar", KeyEvent.VK_C);
        copiar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
        copiar.getAccessibleContext().setAccessibleDescription("Copia el documento seleccionado");
        copiar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se prepara para copiar la parte seleccionada
            }
        });
        menuEdicion.add(copiar);

        JMenuItem pegar = new JMenuItem("Pegar", KeyEvent.VK_V);
        pegar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK));
        pegar.getAccessibleContext().setAccessibleDescription("Pega lo que se copia o corta");
        pegar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se pega la parte que copiamos o que cortamos
            }
        });
        menuEdicion.add(pegar);
        menuEdicion.addSeparator();

        JMenuItem borrar = new JMenuItem("Borrar", KeyEvent.VK_B);
        borrar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.ALT_MASK));
        borrar.getAccessibleContext().setAccessibleDescription("Borra lo que se hizo en su totalidad");
        borrar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //elimina todo lo que se ha realizado en el documento
            }
        });
        menuEdicion.add(borrar);
        menuEdicion.addSeparator();

        // ---------------------------------------------------------------------

        JMenu bordesRelleno = new JMenu("Bordes y Relleno");
        bordesRelleno.setMnemonic(KeyEvent.VK_B);
        bordesRelleno.getAccessibleContext().setAccessibleDescription("Bordes y relleno");

        /**
         * Cada polígono puede ser rellenado, hay tres modos de rellenarlos. El primero 
         * consiste en rellenar utilizando un color plano en RGB. 
         * Otra posibilidad es rellenarlos con un una imagen cargada desde el disco duro
         * (generada por cualquier aplicación) y por último se peude rellenar con una imagen
         * creada por un usuario utilizando figuras como rectángulos y óvalos y con colores 
         * variados, esa imagen debe de poder ser generada 
         * dentro del programa del proyecto y guardada como .jpg o .png.
         */
        JMenuItem tabla = new JMenuItem("Tabla Color");
        tabla.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.ALT_MASK));
        tabla.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
            }
        });
        bordesRelleno.add(tabla);

        JMenuItem hdd = new JMenuItem("Desde Disco Duro");
        hdd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.ALT_MASK));
        hdd.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
            }
        });
        bordesRelleno.add(hdd);

        JMenuItem geometrica = new JMenuItem("Figuras Geométricas");
        geometrica.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.ALT_MASK));
        geometrica.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
            }
        });
        bordesRelleno.add(geometrica);

        menuEdicion.add(bordesRelleno);

        ///////////////////////// MENU IMAGEN /////////////////////////

        JMenu imagen = new JMenu("Imagen");
        imagen.setMnemonic(KeyEvent.VK_I);
        imagen.getAccessibleContext().setAccessibleDescription("Permite rotar imágenes");
        menuPrincipal.add(imagen);

        // acciones del menu "Imagen"

        JMenuItem tamImagen = new JMenuItem("Tamaño de Imagen");
        tamImagen.getAccessibleContext().setAccessibleDescription("Se le otorga el tamaño de la imagen");
        tamImagen.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //se debe poder colocar el tamaño de la imagen
            }
        });
        imagen.add(tamImagen);
        imagen.addSeparator();

        JMenuItem izq = new JMenuItem("Rotar Izquierda", KeyEvent.VK_L);
        izq.setAccelerator(KeyStroke.getKeyStroke('L'));
        izq.getAccessibleContext().setAccessibleDescription("Rota la imagen 90° hacia la izquierda");
        izq.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //debe poder rotar la imagen hacia la izq
            }
        });
        imagen.add(izq);

        JMenuItem der = new JMenuItem("Rotar Derecha", KeyEvent.VK_R);
        der.setAccelerator(KeyStroke.getKeyStroke('R'));
        der.getAccessibleContext().setAccessibleDescription("Rota la imagen 90° hacia la derecha");
        der.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //debe poder rotar la imagen hacia la derecha
            }
        });
        imagen.add(der);
        imagen.addSeparator();

        JMenuItem estirar = new JMenuItem("Estirar", KeyEvent.VK_E);
        estirar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.ALT_MASK));
        estirar.getAccessibleContext().setAccessibleDescription("Estira la imagen sin desfigurar la imagen");
        estirar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //debe estirar la imagen sin desajustarla
            }
        });
        imagen.add(estirar);

        JMenuItem girar = new JMenuItem("Girar");
        girar.getAccessibleContext().setAccessibleDescription("Gira la imagen los grados que se desea");
        girar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //debe girar la imagen dependiendo de los grados que el usuario pida
            }
        });
        imagen.add(girar);

        JMenuItem escalar = new JMenuItem("Escalar");
        escalar.getAccessibleContext().setAccessibleDescription("Estira la imagen solamente en el punto deseado");
        escalar.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //Un polígono puede aumentar su tamaño o reducir su tamaño manteniendo las proporciones con sus 
                //lados y conservando la amplitud de sus ángulos. Esto se logra multiplicando cada punto 
                //de sus vértices por un escalar. En caso que sea mayor que uno, dicho escalar, 
                //el polígono se agranda, si es menor , se encoge
            }
        });
        imagen.add(escalar);


        //////////////// MENU AYUDA ///////////////////

        JMenu menuAyuda = new JMenu("Ayuda");
        menuAyuda.setMnemonic(KeyEvent.VK_Y);
        menuAyuda.getAccessibleContext().setAccessibleDescription("Tutorial para uso del graficador de polígonos");
        menuAyuda.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                //mediante esta accion, se muestra el readme.txt
                readme();
            }
        });
        menuPrincipal.add(menuAyuda);

        setJMenuBar(menuPrincipal);
    }

    public void init() {
        setVisible(true);
        mostrarMensaje("(No hay información disponible)");
    }

    @Override
    public void update(Observable o, Object o1) {
        k++;
        mostrarMensaje(String.format("Se ha actualizado: %s", o1));
    }

    public void cerrarAplicacion() {
        if (confirmar("¿Desea cerrar la aplicación?")) {
            System.out.println("CONFIRMA el cierre de la aplicación..");
            gestorPrincipal.cerrarAplicacion();
        } else {
            System.out.println("CANCELA el cierre de la aplicación..");
        }
    }

    public void mostrarMensaje(String mensaje) {
        msgInfo.setText(mensaje);
    }

    public boolean confirmar(String mensaje) {
        return JOptionPane.showConfirmDialog(this, mensaje, "Confirmación",
                JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
    }

    public void abrirArchivo() {
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new java.io.File("."));
        chooser.setFileFilter(new FileFilter() {

            @Override
            public boolean accept(File f) {
                return f.getName().toLowerCase().endsWith(".xml") || f.getName().toLowerCase().endsWith(".jpg")
                        || f.getName().toLowerCase().endsWith(".png") || f.isDirectory();
            }

            @Override
            public String getDescription() {
                return "XML, JPG, PNG files";
            }
        });
        chooser.setDialogTitle(chooserTitle);
        //
        // disable the "All files" option.
        //
        chooser.setAcceptAllFileFilterUsed(false);

        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            String zipname = chooser.getSelectedFile().getPath();
            System.out.println(zipname);
            dibujarImagen(zipname);

        } else {
            System.out.println("No Selection ");
        }

    }

    public Graphics getGraficos() {
        return areaDibujo.getGraphics();
    }

    public void dibujarCuadrado() {
        Modelo m = gestorPrincipal.obtenerModelo();
        Poligono p = m.getPoligonos().get(0);
        areaDibujo.agregarPoligono(p);
    }

    public void dibujarRectangulo() {
        Modelo m = gestorPrincipal.obtenerModelo();
        Poligono p = m.getPoligonos().get(1);
        areaDibujo.agregarPoligono(p);
    }
    
    public void dibujarRombo(){
        Modelo m = gestorPrincipal.obtenerModelo();
        Poligono p = m.getPoligonos().get(2);
        areaDibujo.agregarPoligono(p);
    }
    
    public void dibujarTriangulo(){
        Modelo m = gestorPrincipal.obtenerModelo();
        Poligono p = m.getPoligonos().get(3);
        areaDibujo.agregarPoligono(p);
    }

    public void borrar(Boolean todo) {
        if (todo) {
            areaDibujo.borrarTodo();
        } else {
            areaDibujo.borrarUltimo();
        }
    }

    public void dibujarImagen(String path) {
        Image imagenExterna = new ImageIcon(path).getImage();
        areaDibujo.setImage(imagenExterna);
        getGraficos().drawImage(imagenExterna, 0, 0, areaDibujo);
    }

    public void readme() {
        JFrame ayudaUsuario = new JFrame();
        ayudaUsuario.setTitle("Ayuda al usuario");
        ayudaUsuario.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        ayudaUsuario.setLayout(new BorderLayout(100, 30));

        JPanel texto = new JPanel();
        ayudaUsuario.add(texto);

        setVisible(true);
       
    }
    private JPanel barraEstado;
    private JPanel barraHerramientas;
    private PanelDibujo areaDibujo;
    private JLabel msgInfo;
    private String chooserTitle;
    private JMenuItem abrir;
    private long k = 0;
    private ControlAplicacion gestorPrincipal = null;
}
